package pl.pasu.mydiet.client;

import java.util.Date;
import java.util.Iterator;
import java.util.List;

import pl.pasu.mydiet.client.dto.DietUserDTO;
import pl.pasu.mydiet.shared.DietResponse;
import pl.pasu.mydiet.shared.Logger;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class MyDiet {
	private static final String LOG_TAG = "MyDiet";

	/**
	 * Create a remote service proxy to talk to the server-side Greeting
	 * service.
	 */
	private final DietServiceAsync dietService = GWT.create(DietService.class);

	private RootPanel panelRegister;
	private RootPanel panelLogin;
	private RootPanel panelChat;
	private RootPanel panelFind;
	final Button registerButton = new Button("Register");
	final Button loginButton = new Button("Login");
	final Button findButton = new Button("Find Friends");
	final Button chatButton = new Button("Chat");
	final Label errorLabel = new Label("");
	final Label errorStackTraceLabel = new Label("");
	final Label successLabel = new Label("");
	final Label tempLabel = new Label("");

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		panelRegister = RootPanel.get("workingAreaContainerRegister");
		panelLogin = RootPanel.get("workingAreaContainerLogin");
		panelChat = RootPanel.get("workingAreaContainerChat");
		panelFind = RootPanel.get("workingAreaContainerFind");

		// We can add style names to widgets
		registerButton.addStyleName("menuButton");
		loginButton.addStyleName("menuButton");
		findButton.addStyleName("menuButton");
		chatButton.addStyleName("menuButton");

		errorLabel.addStyleName("errorLabel");
		errorStackTraceLabel.addStyleName("errorLabel");
		successLabel.addStyleName("successLabel");
		tempLabel.addStyleName("successLabel");

		// Add the nameField and sendButton to the RootPanel
		// Use RootPanel.get() to get the entire body element
		RootPanel.get("registerButtonContainer").add(registerButton);
		RootPanel.get("loginButtonContainer").add(loginButton);
		RootPanel.get("findFriendsButtonContainer").add(findButton);
		RootPanel.get("chatButtonContainer").add(chatButton);
		RootPanel.get("errorLabelContainer").add(errorLabel);
		RootPanel.get("successLabelContainer").add(successLabel);
		RootPanel.get("tempArea").add(tempLabel);
		RootPanel.get("errorStackTraceLabelContainer")
				.add(errorStackTraceLabel);

		final TextBox username = new TextBox();
		username.addStyleName("showInBlock");
		final PasswordTextBox pass = new PasswordTextBox();
		pass.addStyleName("showInBlock");
		final Button doneRegisterButton = new Button("Register");
		doneRegisterButton.addStyleName("showInBlock");

		registerButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				Logger.d(LOG_TAG, "register click");
				clearLabels();
				clearPanels();
				enableButtons();
				registerButton.setEnabled(false);
				panelRegister.add(new Label("User name:"));
				panelRegister.add(username);
				panelRegister.add(new Label("Password:"));
				panelRegister.add(pass);
				panelRegister.add(doneRegisterButton);
			}
		});

		final Button doneLoginButton = new Button("Login");
		doneRegisterButton.addStyleName("showInBlock");
		loginButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				Logger.d(LOG_TAG, "login click");
				clearLabels();
				clearPanels();
				enableButtons();
				loginButton.setEnabled(false);
				panelLogin.add(username);
				panelLogin.add(pass);
				panelLogin.add(doneLoginButton);
			}
		});

		doneRegisterButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				Logger.d(LOG_TAG, "register done click");
				clearLabels();
				DietUserDTO user = new DietUserDTO(null, username.getText(),
						pass.getText(), new Date(System.currentTimeMillis()),
						null);
				dietService.createUser(user, new AsyncCallback<DietResponse>() {
					public void onFailure(Throwable caught) {
						Logger.d(LOG_TAG, "createUser onFailure\n");
						Logger.d(LOG_TAG, caught.getMessage());
						caught.printStackTrace();
						StackTraceElement[] stack = caught.getStackTrace();
						StringBuilder b = new StringBuilder();
						for (int i = 0; i < stack.length; i++) {
							b.append(stack[i] + "/n");
						}
						errorLabel
								.setText("ERROR! see below stack trace for details");
						errorStackTraceLabel.setText("ERROR stack trace /n"
								+ b.toString());

						// Show the RPC error message to the user
						// dialogBox
						// .setText("Remote Procedure Call - Failure");
						// serverResponseLabel
						// .addStyleName("serverResponseLabelError");
						// serverResponseLabel.setHTML(SERVER_ERROR);
						// dialogBox.center();
						// closeButton.setFocus(true);
					}

					public void onSuccess(DietResponse result) {
						Logger.d(LOG_TAG, "createUser onSuccess");
						Logger.d(
								LOG_TAG,
								"result: code= " + result.getResponseCode()
										+ ", msg="
										+ result.getResponseMessage());
						successLabel.setText("result: code= "
								+ result.getResponseCode() + ", msg="
								+ result.getResponseMessage());
						// dialogBox.setText("Remote Procedure Call");
						// serverResponseLabel
						// .removeStyleName("serverResponseLabelError");
						// serverResponseLabel.setHTML(result);
						// dialogBox.center();
						// closeButton.setFocus(true);
					}
				});
			}
		});

		findButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				Logger.d(LOG_TAG, "find click");
				dietService.getUsers(new AsyncCallback<List<DietUserDTO>>() {
					public void onFailure(Throwable caught) {
						Logger.d(LOG_TAG, "getUsers onFailure\n");
						Logger.d(LOG_TAG, caught.getMessage());
						caught.printStackTrace();
						StackTraceElement[] stack = caught.getStackTrace();
						StringBuilder b = new StringBuilder();
						for (int i = 0; i < stack.length; i++) {
							b.append(stack[i] + "/n");
						}
						errorLabel
								.setText("ERROR! see below stack trace for details");
						errorStackTraceLabel.setText("ERROR stack trace /n"
								+ b.toString());

					}

					public void onSuccess(List<DietUserDTO> result) {
						Logger.d(LOG_TAG, "getUsers onSuccess");
						StringBuilder b = new StringBuilder();
						for (Iterator<DietUserDTO> iterator = result.iterator(); iterator
								.hasNext();) {
							DietUserDTO dietUserDTO = iterator.next();
							b.append("USER: " + dietUserDTO.toString() + "\n");
						}
						tempLabel.setText(b.toString());

					}
				});
			}
		});

		// // Focus the cursor on the name field when the app loads
		// nameField.setFocus(true);
		// nameField.selectAll();

		// Create the popup dialog box
		final DialogBox dialogBox = new DialogBox();
		dialogBox.setText("Remote Procedure Call");
		dialogBox.setAnimationEnabled(true);
		final Button closeButton = new Button("Close");
		// We can set the id of a widget by accessing its Element
		closeButton.getElement().setId("closeButton");
		final Label textToServerLabel = new Label();
		final HTML serverResponseLabel = new HTML();
		VerticalPanel dialogVPanel = new VerticalPanel();
		dialogVPanel.addStyleName("dialogVPanel");
		dialogVPanel.add(new HTML("<b>Sending name to the server:</b>"));
		dialogVPanel.add(textToServerLabel);
		dialogVPanel.add(new HTML("<br><b>Server replies:</b>"));
		dialogVPanel.add(serverResponseLabel);
		dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
		dialogVPanel.add(closeButton);
		dialogBox.setWidget(dialogVPanel);

		// Add a handler to close the DialogBox
		closeButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				dialogBox.hide();
			}
		});

	}

	private void clearLabels() {
		tempLabel.setText("");
		errorLabel.setText("");
		errorStackTraceLabel.setText("");
		successLabel.setText("");
	}

	private void enableButtons() {
		registerButton.setEnabled(true);
		loginButton.setEnabled(true);
		findButton.setEnabled(true);
		chatButton.setEnabled(true);
	}

	private void clearPanels() {
		panelRegister.clear();
		panelLogin.clear();
		panelChat.clear();
		panelFind.clear();
	}
}
